home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / fw_xemacs.idb / usr / freeware / lib / xemacs-20.4 / lisp / w3 / w3-latex.el.z / w3-latex.el
Encoding:
Text File  |  1998-05-21  |  14.0 KB  |  459 lines

  1. ;;; w3-latex.el --- Emacs-W3 printing via LaTeX
  2. ;; Author: wmperry
  3. ;; Created: 1996/06/30 18:08:34
  4. ;; Version: 1.3
  5. ;; Keywords: hypermedia, printing, typesetting
  6.  
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8. ;;; Copyright (c) 1996, 1997 by Stephen Peters <speters@cygnus.com>
  9. ;;;
  10. ;;; This file is not part of GNU Emacs, but the same permissions apply.
  11. ;;;
  12. ;;; GNU Emacs is free software; you can redistribute it and/or modify
  13. ;;; it under the terms of the GNU General Public License as published by
  14. ;;; the Free Software Foundation; either version 2, or (at your option)
  15. ;;; any later version.
  16. ;;;
  17. ;;; GNU Emacs is distributed in the hope that it will be useful,
  18. ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. ;;; GNU General Public License for more details.
  21. ;;;
  22. ;;; You should have received a copy of the GNU General Public License
  23. ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
  24. ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25. ;;; Boston, MA 02111-1307, USA.
  26. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  27. ;;; Elisp code to convert a W3 parse tree into a LaTeX buffer.
  28. ;;;
  29. ;;; Heavily hacked upon by William Perry <wmperry@cs.indiana.edu> to add more
  30. ;;; bells and whistles.
  31. ;;;
  32. ;;; KNOWN BUGS:
  33. ;;; 1) This does not use stylesheets to get the formatting information
  34. ;;; 2) This means that the new drawing routines need to be abstracted
  35. ;;;    further so that the same main engine can be used for either
  36. ;;;    text-output (standard stuff in w3-draw), LaTeX output (this file),
  37. ;;;    Postscript (to-be-implemented), etc., etc.
  38. ;;; 3) This still doesn't handle tables.
  39. ;;;
  40. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  41. (require 'w3-cus)
  42. (require 'w3-print)
  43.  
  44. ;; Internal variables - do not touch!
  45. (defvar w3-latex-current-url nil "What URL we are formatting")
  46. (defvar w3-latex-verbatim nil "Whether we are in a {verbatim} block or not")
  47. (defvar w3-latex-links-list nil "List of links for endnote usage")
  48.  
  49. (defvar w3-latex-entities
  50.   '((nbsp . "~")
  51.     (iexcl . "!`")
  52. ;   (cent . "")
  53.     (pound . "\\pounds ")
  54. ;   (curren . "")
  55. ;   (yen . "")
  56.     (brvbar . "|")
  57.     (sect . "\\S")
  58.     (uml . "\\\"{ }")
  59.     (copy . "\\copyright ")
  60. ;   (ordf . "")
  61.     (laquo . "$\\ll$")
  62.     (not . "\\neg")
  63.     (shy . "-")
  64.     (reg . "(R)")
  65.     (macr . "\\={ }")
  66.     (deg . "$\\deg$")
  67.     (plusmn . "$\\pm$")
  68.     (sup2 . "$^{2}$")
  69.     (sup3 . "$^{3}$")
  70.     (acute . "\\'{ }")
  71.     (micro . "$\\mu$")
  72.     (para . "\\P ")
  73.     (middot . "$\\cdot$")
  74.     (cedil . "\\c{ }")
  75.     (sup1 . "$^{1}$")
  76. ;   (ordm . "")
  77.     (raquo . "$\\gg$")
  78.     (frac14 . "$\frac{1}{4}$")
  79.     (frac12 . "$\frac{1}{2}$")
  80.     (frac34 . "$\frac{3}{4}$")
  81.     (iquest . "?`")
  82.     (Agrave . "\\`{A}")
  83.     (Aacute . "\\'{A}")
  84.     (Acirc . "\\^{A}")
  85.     (Atilde . "\\~{A}")
  86.     (Auml . "\\\"{A}")
  87.     (Aring . "\\AA ")
  88.     (AElig . "\\AE ")
  89.     (Ccedil . "\\c{C}")
  90.     (Egrave . "\\`{E}")
  91.     (Eacute . "\\'{E}")
  92.     (Ecirc . "\\^{E}")
  93.     (Euml . "\\\"{E}")
  94.     (Igrave . "\\`{I}")
  95.     (Iacute . "\\'{I}")
  96.     (Icirc . "\\^{I}")
  97.     (Iuml . "\\\"{I}")
  98. ;   (ETH . "")
  99.     (Ntilde . "\\~{N}")
  100.     (Ograve . "\\`{O}")
  101.     (Oacute . "\\'{O}")
  102.     (Ocirc . "\\^{O}")
  103.     (Otilde . "\\~{O}")
  104.     (Ouml . "\\\"{O}")
  105.     (times . "$\\times$")
  106.     (Oslash . "\\O")
  107.     (Ugrave . "\\`{U}")
  108.     (Uacute . "\\'{U}")
  109.     (Ucirc . "\\^{U}")
  110.     (Uuml . "\\\"{U}")
  111.     (Yacute . "\\'{Y}")
  112. ;   (THORN . "")
  113.     (szlig . "\\ss ")
  114.     (agrave . "\\`{a}")
  115.     (aacute . "\\'{a}")
  116.     (acirc . "\\^{a}")
  117.     (atilde . "\\~{a}")
  118.     (auml . "\\\"{a}")
  119.     (aring . "\\aa ")
  120.     (aelig . "\\ae ")
  121.     (ccedil . "\\c{c}")
  122.     (egrave . "\\`{e}")
  123.     (eacute . "\\'{e}")
  124.     (ecirc . "\\^{e}")
  125.     (euml . "\\\"{e}")
  126.     (igrave . "\\`{i}")
  127.     (iacute . "\\'{i}")
  128.     (icirc . "\\^{i}")
  129.     (iuml . "\\\"{i}")
  130. ;   (eth . "")
  131.     (ntilde . "\\~{n}")
  132.     (ograve . "\\`{o}")
  133.     (oacute . "\\'{o}")
  134.     (ocirc . "\\^{o}")
  135.     (otilde . "\\~{o}")
  136.     (ouml . "\\\"{o}")
  137.     (divide . "$\\div$")
  138.     (oslash . "\\o")
  139.     (ugrave . "\\`{u}")
  140.     (uacute . "\\'{u}")
  141.     (ucirc . "\\^{u}")
  142.     (uuml . "\\\"{u}")
  143.     (yacute . "\\'{y}")
  144. ;   (thorn . "")
  145.     (yuml . "\\\"{y}"))
  146.   "Defines mappings between `w3-html-entities' and LaTeX characters.") 
  147.  
  148. (defun w3-latex-replace-entities (str)
  149.   (let ((start 0))
  150.     (while (string-match "[\200-\377]" str start)
  151.       ; get the character code, and then search for a match in
  152.       ; w3-html-entities.  If one is found, use it to perform a lookup
  153.       ; in w3-latex-entities, and use the resulting match to replace
  154.       ; the character.
  155.       (let* ((match (rassq (aref str (match-beginning 0))
  156.                w3-html-entities))
  157.          (replace (and match
  158.                (assq (car match) w3-latex-entities))))
  159.     (if replace
  160.         (setq str (replace-match (cdr replace) t t str)))
  161.     (setq start (match-end 0))))
  162.     str))
  163.  
  164. (defun w3-latex-insert-string (str)
  165.   ;;; convert string to a LaTeX-compatible one.
  166.   (let ((todo (list (cons "\\\\"          "-BaCkSlAsH-")
  167.             (cons "[%&#_{}$]"     "\\\\\\&")
  168.             (cons "\\^"           "{\\\\textasciicircum}")
  169.             (cons "~"             "{\\\\textasciitilde}")
  170.             (cons "[*]"           "{\\&}")
  171.             (cons "[><|]"         "$\\&$")
  172.             (cons "-BaCkSlAsH-"   "$\\\\backslash$"))))
  173.     (if w3-latex-verbatim
  174.     (setq todo (append todo '(("\n" . "\\\\newline\\\\nullspace\n")
  175.                   (" " . "\\\\ ")))))
  176.     (save-excursion
  177.       (set-buffer (get-buffer-create " *w3-latex-munging*"))
  178.       (erase-buffer)
  179.       (insert str)
  180.       (while todo
  181.     (goto-char (point-min))
  182.     (while (re-search-forward (caar todo) nil t)
  183.       (replace-match (cdar todo)))
  184.     (setq todo (cdr todo)))
  185.       (setq str (w3-latex-replace-entities (buffer-string))))
  186.     (insert str)))
  187.  
  188. (defun w3-latex-ignore (tree)
  189.   ;;; ignores any contents of this tree.
  190.   nil)
  191.  
  192. (defun w3-latex-contents (tree)
  193.   ;;; passes contents of subtree through to the latex-subtree
  194.   (let ((contents (car (cdr (cdr tree)))))
  195.     (while contents
  196.       (w3-latex-subtree (car contents))
  197.       (setq contents (cdr contents)))))
  198.  
  199. (defun w3-latex-html (tree)
  200.   (insert "% This document automatically generated by Emacs-W3 v"
  201.       w3-version-number "\n")
  202.   (if w3-latex-current-url
  203.       (insert "% from <URL:" w3-latex-current-url ">\n"))
  204.   (insert "%\n"
  205.       "\\batchmode\n\\begin{document}\n")
  206.   (insert "\\setlength{\\parindent}{0pt}\n"
  207.       "\\setlength{\\parskip}{1.5ex}\n")
  208.   (insert "\\newcommand{\\nullspace}{\\rule{0pt}{0pt}}")
  209.   (w3-latex-contents tree)
  210.   (if w3-latex-links-list (w3-latex-endnotes))
  211.   (insert "\\end{document}\n"))
  212.  
  213. (defun w3-latex-title (tree)
  214.   (if w3-latex-use-maketitle
  215.       (insert "\\title{")
  216.     (insert "\\section*{\\centering "))
  217.   (w3-latex-contents tree)
  218.   (insert "}\n")
  219.   (if w3-latex-use-maketitle
  220.       (insert "\\author{}\\date{}\n\\maketitle")))
  221.  
  222. (defun w3-latex-heading (tree)
  223.   ;; look through the additional markup to see if an align=right or
  224.   ;; align=center is in here...
  225.   (let ((align (assq 'align (car (cdr tree))))
  226.     (sym (car tree)))
  227.     (insert "\n\n")
  228.     (cond ((and align (string-equal (cdr align) "center"))
  229.        (insert "\\begin{center}\n"))
  230.       ((and align (string-equal (cdr align) "right"))
  231.        (insert "\\begin{flushright}\n")))
  232.     (cond ((eq sym 'h1) (insert "\\section*{"))
  233.       ((eq sym 'h2) (insert "\\subsection*{"))
  234.       ((eq sym 'h3) (insert "\\subsubsection*{"))
  235.       ((eq sym 'h4) (insert "\\subsubsection*{"))
  236.       ((eq sym 'h5) (insert "\\paragraph*{"))
  237.       ((eq sym 'h6) (insert "\\subparagraph*{")))
  238.     (w3-latex-contents tree)
  239.     (insert "}\n")
  240.     (cond ((and align (string-equal (cdr align) "center"))
  241.        (insert "\\end{center}\n"))
  242.       ((and align (string-equal (cdr align) "right"))
  243.        (insert "\\end{flushright}\n")))))
  244.  
  245. (defun w3-latex-bold (tree)
  246.   (insert "{\\bf ")
  247.   (w3-latex-contents tree)
  248.   (insert "}"))
  249. (defun w3-latex-italic (tree)
  250.   (insert "{\\em ")
  251.   (w3-latex-contents tree)
  252.   (insert "}"))
  253. (defun w3-latex-typewriter (tree)
  254.   (insert "{\\tt ")
  255.   (w3-latex-contents tree)
  256.   (insert "}"))
  257.  
  258. (defun w3-latex-list (tree)
  259.   (let* ((sym (car tree))
  260.      (list-type (cond ((eq sym 'ol) "enumerate")
  261.               ((eq sym 'dl) "description")
  262.               (t "itemize"))))
  263.     (insert (concat "\n\\begin{" list-type "}\n"))
  264.     (w3-latex-contents tree)
  265.     (insert (concat "\n\\end{" list-type "}\n"))))
  266.  
  267. (defun w3-latex-list-item (tree)
  268.   (let ((sym (car tree)))
  269.     (cond ((eq sym 'dt)
  270.        (insert "\n\\item["))
  271.       ((eq sym 'dd)
  272.        ;; don't do anything for dd -- the item is handled by dt.
  273.        nil)
  274.       (t (insert "\n\\item")))
  275.     (w3-latex-contents tree)
  276.     (if (eq sym 'dt)
  277.     (insert "]"))))
  278.  
  279. (defun w3-latex-center (tree)
  280.   (insert "\\begin{center}")
  281.   (w3-latex-contents tree)
  282.   (insert "\\end{center}"))
  283.  
  284. (defun w3-latex-rule (tree)
  285.   ; use \par to make paragraph division clear.
  286.   (insert "\n\\par\\noindent\\rule{\\textwidth}{.01in}\n"))
  287.  
  288. (defun w3-latex-para (tree)
  289.   ;; look through the additional markup to see if an align=right or
  290.   ;; align=center is in here...
  291.   (let ((align (assq 'align (car (cdr tree)))))
  292.     (cond ((and align
  293.         (string-equal (cdr align) "center"))
  294.        (w3-latex-center tree))
  295.       ((and align
  296.         (string-equal (cdr align) "right"))
  297.        (insert "\\begin{flushright}")
  298.        (w3-latex-contents tree)
  299.        (insert "\\end{flushright}"))
  300.       (t (insert "\\par ")
  301.          (w3-latex-contents tree)))))
  302.  
  303. (defun w3-latex-quote (tree)
  304.   (insert "\\begin{quote}\n")
  305.   (w3-latex-contents tree)
  306.   (insert "\\end{quote}\n"))
  307.  
  308. (defun w3-latex-break (tree)
  309.   ;; no content allowed
  310.   (insert "\\newline "))
  311.  
  312. (defun w3-latex-endnotes ()
  313.   (let ((i 1))
  314.     (insert "\\begin{thebibliography}{99}\n")
  315.     (while w3-latex-links-list
  316.       (insert (concat "\\bibitem{ref" (number-to-string i) "}"))
  317.       (w3-latex-insert-string (car w3-latex-links-list))
  318.       (insert "\n")
  319.       (setq w3-latex-links-list (cdr w3-latex-links-list))
  320.       (setq i (1+ i)))
  321.     (insert "\\end{thebibliography}\n")))
  322.  
  323. (defun w3-latex-href (tree)
  324.   (let ((href (cdr-safe (assq 'href (cadr tree))))
  325.     (name (cdr-safe (assq 'name (cadr tree)))))
  326.     (cond
  327.      ((not w3-latex-print-links)    ; No special treatment
  328.       (w3-latex-contents tree))
  329.      (name
  330.       (w3-latex-contents tree)
  331.       (insert (concat "\\label{" name "}")))
  332.      (href                ; Special treatment requested
  333. ;      (insert "\\underline{")        ; and we have a URL - underline
  334.       (w3-latex-contents tree)        ; it.
  335. ;      (insert "}")
  336.       (cond 
  337.        ((char-equal ?# (aref href 0))
  338.     (insert (concat " (see page~\\pageref{"
  339.             (substring href 1)
  340.             "})")))
  341.        ((eq w3-latex-print-links 'footnote)
  342.     (insert "\\footnote{")        ; Request to prepare footnote 
  343.     (w3-latex-insert-string href)
  344.     (insert "}"))
  345.        (t                ; Otherwise, prepare endnotes
  346.     (let ((mem (member href w3-latex-links-list))
  347.           (i (1+ (length w3-latex-links-list))))
  348.       (if mem
  349.           (setq i (- i (length mem)))
  350.         (setq w3-latex-links-list
  351.           (append w3-latex-links-list (cons href nil))))
  352.       (insert (concat "~\\cite{ref" (number-to-string i) "}"))))))
  353.      (t                    ; Special treatment requested, but
  354.       (w3-latex-contents tree)))))    ; no URL - do nothing.
  355.  
  356. (defun w3-latex-preformatted (tree)
  357.   (let ((w3-latex-verbatim t))
  358.     (insert "\\par\\noindent\\begin{tt}")
  359.     (w3-latex-contents tree)
  360.     (insert "\\end{tt}\\par")
  361.     ))
  362.  
  363. (defun w3-latex-xmp (tree)
  364.   (insert "\\begin{verbatim}")
  365.   (w3-latex-contents tree)
  366.   (insert "\\end{verbatim}"))
  367.  
  368. (let ((todo '((title . w3-latex-title)
  369.           (html . w3-latex-html)
  370.           (pre . w3-latex-preformatted)
  371.           (xmp . w3-latex-xmp)
  372.           (h1 . w3-latex-heading)
  373.           (h2 . w3-latex-heading)
  374.           (h3 . w3-latex-heading)
  375.           (h4 . w3-latex-heading)
  376.           (h5 . w3-latex-heading)
  377.           (h6 . w3-latex-heading)
  378.           (a  . w3-latex-href)
  379.           (strong . w3-latex-bold)
  380.           (b . w3-latex-bold)
  381.           (dfn . w3-latex-bold)
  382.           (em . w3-latex-italic)
  383.           (i . w3-latex-italic)
  384.           (address . w3-latex-italic)
  385.           (code . w3-latex-typewriter)
  386.           (samp . w3-latex-typewriter) 
  387.           (tt . w3-latex-typewriter)
  388.           (kbd . w3-latex-typewriter) 
  389.           (var . w3-latex-typewriter)
  390.           (ol . w3-latex-list)
  391.           (dl . w3-latex-list)
  392.           (ul . w3-latex-list) 
  393.           (menu . w3-latex-list)
  394.           (dir . w3-latex-list)
  395.           (li . w3-latex-list-item)
  396.           (dt . w3-latex-list-item) 
  397.           (dd . w3-latex-list-item)
  398.           (center . w3-latex-center)
  399.           (hr . w3-latex-rule)
  400.           (p . w3-latex-para)
  401.           (br . w3-latex-break)
  402.           (blockquote . w3-latex-quote))))
  403.   (while todo
  404.     (put (caar todo) 'w3-latex-formatter (cdar todo))
  405.     (setq todo (cdr todo))))
  406.  
  407. (defun w3-latex-subtree (tree)
  408.   (cond
  409.    ((stringp tree)
  410.     (w3-latex-insert-string tree))
  411.    ((stringp (car-safe tree))
  412.     (while tree
  413.       (w3-latex-insert-string (car tree))
  414.       (setq tree (cdr tree))))
  415.    ((symbolp (car tree))
  416.     (let ((proc (get (car tree) 'w3-latex-formatter)))
  417.       (if (and proc (fboundp proc))
  418.       (funcall proc tree)
  419.     ;; anything else gets passed through unchanged
  420.     (w3-latex-contents tree))))
  421.    (t
  422.     (w3-latex-contents tree))))
  423.  
  424. ;;;###autoload
  425. (defun w3-parse-tree-to-latex (tree &optional url)
  426.   ; assumes that url-working-buffer exists.
  427.   (set-buffer (get-buffer-create url-working-buffer))
  428.   (setq w3-latex-current-url url)
  429.   (erase-buffer)
  430.   (goto-char (point-min))
  431.   (if w3-latex-use-latex2e
  432.       (insert (concat "\\documentclass" w3-latex-docstyle "\n"))
  433.     (insert (concat "\\documentstyle" w3-latex-docstyle "\n")))
  434.   (if (and w3-latex-use-latex2e
  435.        w3-latex-packages)
  436.       (insert (apply 'concat
  437.              (mapcar (lambda (x) (concat "\\usepackage{" x "}\n"))
  438.                  w3-latex-packages))))
  439.   (while tree
  440.     (w3-latex-subtree (car tree))
  441.     (setq tree (cdr tree))))
  442.  
  443. ;;;###autoload
  444. (defun w3-show-dvi ()
  445.   "Uses xdvi to show DVI file created from `w3-parse-tree-to-latex'."
  446.   (interactive)
  447.   (w3-parse-tree-to-latex w3-current-parse)
  448.   (save-window-excursion
  449.     (set-buffer url-working-buffer)
  450.     (write-region (point-min) (point-max)
  451.           (expand-file-name "w3-tmp.latex"
  452.                     w3-temporary-directory) nil 5)
  453.     (shell-command
  454.      (format 
  455.       "(cd %s ; latex w3-tmp.latex ; latex w3-tmp.latex ; xdvi w3-tmp.dvi ; rm -f w3-tmp*) &"
  456.       w3-temporary-directory))))
  457.  
  458. (provide 'w3-latex)
  459.